import type { Rule, AST } from "eslint";

function isStyleElement(node) {
  return node.type === "VElement" && node.name === "style";
}

function isNotScopeStyle(styleNode) {
  return (styleNode.startTag.attributes || []).every(attribute => attribute.key.name !== "scoped" && attribute.key.name !== "module");
}

export const rule: Rule.RuleModule = {
  meta: {
    docs: {
      description: "ESLint plugin to require Vue style tags with scoped or module attribute.",
    },
  },

  create(context) {
    const rootAST = context.parserServices.getDocumentFragment && context.parserServices.getDocumentFragment();

    let notScopeStyleNodes = [];
    if (rootAST) {
      let styles = rootAST.children.filter(isStyleElement);

      notScopeStyleNodes = styles.filter(isNotScopeStyle);
    }

    return {
      "Program:exit"() {
        notScopeStyleNodes.forEach(node => {
          context.report({
            node: node,
            loc: node.startTag.loc,
            message: "The <style> tag should have scoped or module attribute.",
          });
        });
      },
    };
  },
};
